package com.example.springbootdemo.util;

import java.io.IOException;
import java.io.StringWriter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.geotools.data.DataUtilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.referencing.CRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geometry.jts.JTS;
import java.io.StringReader;

import org.opengis.referencing.FactoryException;
import org.opengis.referencing.operation.TransformException;
import org.springframework.boot.configurationprocessor.json.JSONException;

public class CoordinateConverter {

    public static String convertGeoJsonCollectionToTargetCrs(String geoJson, String sourceCrsCode, String targetCrsCode) throws Exception {
        // 参数校验（复用原有逻辑）
        if (geoJson == null || geoJson.trim().isEmpty()) {
            throw new IllegalArgumentException("GeoJSON字符串不能为空");
        }
        try {
            new ObjectMapper().readTree(geoJson);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("无效的GeoJSON格式", e);
        }

        // 坐标系校验
        CoordinateReferenceSystem sourceCrs = CRS.decode(sourceCrsCode);
        CoordinateReferenceSystem targetCrs = CRS.decode(targetCrsCode);
        MathTransform transform = CRS.findMathTransform(sourceCrs, targetCrs, true);

        try (StringReader reader = new StringReader(geoJson)) {
            FeatureJSON featureJSON = new FeatureJSON();

            // 1. 解析要素集合

            FeatureCollection<SimpleFeatureType, SimpleFeature> rawCollection = featureJSON.readFeatureCollection(reader);
            SimpleFeatureCollection featureCollection = DataUtilities.simple(rawCollection);//name type geometry

            // 2. 创建目标集合
            DefaultFeatureCollection convertedCollection = new DefaultFeatureCollection();

            try (SimpleFeatureIterator iterator = featureCollection.features()) {
                while (iterator.hasNext()) {
                    SimpleFeature feature = iterator.next();

                    // 3. 转换几何坐标
                    Geometry geometry = (Geometry) feature.getDefaultGeometry();
                    Geometry transformedGeometry = JTS.transform(geometry, transform);

                    // 4. 创建新要素保留原有属性
                    SimpleFeatureBuilder builder = new SimpleFeatureBuilder(feature.getFeatureType());
                    builder.init(feature);
                    builder.set(feature.getFeatureType().getGeometryDescriptor().getName(), transformedGeometry);
                    SimpleFeature newFeature = builder.buildFeature(feature.getID());

                    convertedCollection.add(newFeature);
                }
            }

            // 5. 序列化结果
            StringWriter writer = new StringWriter();
            featureJSON.writeFeatureCollection(convertedCollection, writer);
            return writer.toString();

        } catch ( TransformException e) {
            throw new Exception("坐标转换失败: " + e.getMessage(), e);
        } catch (IOException e) {
            throw new Exception("IO异常: " + e.getMessage(), e);
        }catch (Exception e) {
            throw new Exception("坐标转换过程中发生未知错误: " + e.getMessage(), e);
        }
    }


    public static String convertGeoJsonToTargetCrs(String geoJson, String sourceCrsCode, String targetCrsCode) throws Exception {
        // 校验GeoJSON格式
        if (geoJson == null || geoJson.trim().isEmpty()) {
            throw new IllegalArgumentException("GeoJSON字符串不能为空");
        }
        try {
            // 修改校验逻辑
            ObjectMapper mapper = new ObjectMapper();
            mapper.readTree(geoJson); // 替换new JSONObject()
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("无效的GeoJSON格式", e);
        }

        // 校验坐标系代码
        if (sourceCrsCode == null || sourceCrsCode.trim().isEmpty()) {
            throw new IllegalArgumentException("源坐标系代码不能为空");
        }
        if (targetCrsCode == null || targetCrsCode.trim().isEmpty()) {
            throw new IllegalArgumentException("目标坐标系代码不能为空");
        }

        try {
            // 解析GeoJSON
            FeatureJSON featureJSON = new FeatureJSON();
            SimpleFeature feature = featureJSON.readFeature(new StringReader(geoJson));

            // 1获取源坐标系和目标坐标系
            CoordinateReferenceSystem sourceCrs = CRS.decode(sourceCrsCode);
            CoordinateReferenceSystem targetCrs = CRS.decode(targetCrsCode);

            // 2创建坐标转换
            MathTransform transform = CRS.findMathTransform(sourceCrs, targetCrs, true);

            // 3获取几何对象并转换坐标系
            Geometry geometry = (Geometry) feature.getDefaultGeometry();
            Geometry transformedGeometry = JTS.transform(geometry, transform);

            // 更新要素的几何对象
            feature.setDefaultGeometry(transformedGeometry);

            // 将转换后的要素写回GeoJSON
            StringWriter writer = new StringWriter();
            featureJSON.writeFeature(feature, writer);
            return writer.toString();
        } catch (FactoryException e) {
            throw new Exception("无法解析坐标系代码: " + e.getMessage(), e);
        } catch (TransformException e) {
            throw new Exception("坐标转换失败: " + e.getMessage(), e);
        } catch (IOException e) {
            throw new Exception("GeoJSON解析或写入失败: " + e.getMessage(), e);
        } catch (Exception e) {
            throw new Exception("坐标转换过程中发生未知错误: " + e.getMessage(), e);
        }
    }
}